19677
15356
بعد قراءة Hidden Features and Dark Corners of C ++ / STL on comp.lang.c ++. خاضعة للإشراف ، فوجئت تمامًا بأن المقتطف التالي تم تجميعه وعمله في كل من Visual Studio 2008 و G ++ 4.4.
ها هو الكود:
# تضمين 
انت مين()
{
كثافة العمليات س = 10 ؛
بينما (x -> 0) // x يذهب إلى 0
{
printf ("٪ d" ، x) ؛
}
}
انتاج:
9 8 7 6 5 4 3 2 1 0
أفترض أن هذا هو C ، لأنه يعمل في دول مجلس التعاون الخليجي أيضًا. من أين يتم تعريف هذا في المعيار ومن أين أتى؟ 
-> ليس عامل تشغيل. إنه في الواقع عاملان منفصلان ، - و>.
ينقص الكود الشرطي x ، أثناء إرجاع قيمة x الأصلية (غير المتناقصة) ، ثم يقارن القيمة الأصلية بـ 0 باستخدام عامل التشغيل>.
لفهم أفضل ، يمكن كتابة البيان على النحو التالي:
بينما ((س--)> 0)
|
أو لشيء مختلف تمامًا ... شرائح x إلى 0.
بينما (س - \
\
\
\
> 0)
printf ("٪ d" ، x) ؛
ليست رياضية للغاية ، لكن ... كل صورة ترسم ألف كلمة ...
|
هذا عامل معقد للغاية ، لذلك حتى ISO / IEC JTC1 (اللجنة الفنية المشتركة 1) وضعت وصفها في جزأين مختلفين من معيار C ++.
وبغض النظر عن المزاح ، فهما عاملان مختلفان: - و> موصوفان على التوالي في الفقرتين 5.2.6 / 2 و 5.9 من معيار C ++ 03.
|
إنه يعادل
بينما (x--> 0)
x-- (التناقص اللاحق) يعادل x = x-1 لذلك ، يتحول الكود إلى:
بينما (x> 0) {
س = س -1 ؛
// منطق
}
س-- ؛ // تم إجراء إنقاص اللاحق عندما x <= 0
|
يمكن أن تذهب x إلى الصفر أسرع في الاتجاه المعاكس:
كثافة العمليات س = 10 ؛
بينما (0 <---- x)
{
printf ("٪ d" ، x) ؛
}
8 6 4 2
يمكنك التحكم في السرعة بسهم!
كثافة العمليات س = 100 ؛
بينما (0 <-------------------- x)
{
printf ("٪ d" ، x) ؛
}
90 80 70 60 50 40 30 20 10
؛)
|
انها
# تضمين 
int main (void) {
كثافة العمليات س = 10 ؛
بينما (x--> 0) {// x يذهب إلى 0
printf ("٪ d" ، x) ؛
}
العودة 0 ؛
}
مجرد المساحة تجعل الأشياء تبدو مضحكة - تناقص و> يقارن.
|
استخدام -> له صلة تاريخية. كان التناقص (ولا يزال في بعض الحالات) أسرع من الزيادة في بنية x86. يشير استخدام -> إلى أن x ستذهب إلى 0 ، وتروق لمن لديهم خلفيات رياضية.
|
بينما (x--> 0)
كيف يتم تحليل ذلك.
|
مهووس تمامًا ، لكنني سأستخدم هذا:
# تعريف كـ ؛ بينما
int main (int argc، char * argv [])
{
int n = atoi (argv [1]) ؛
قم بإجراء printf ("n هو٪ d \ n" ، n) كـ (n -> 0) ؛
العودة 0 ؛
}
|
كتاب واحد قرأته (لا أتذكر بشكل صحيح أي كتاب) ذكر: يحاول المجمّعون تحليل التعبيرات إلى أكبر رمز باستخدام القاعدة اليمنى اليسرى.
في هذه الحالة ، التعبير:
س -> 0
توزيع لأكبر الرموز المميزة:
الرمز المميز 1: x
الرمز المميز 2: -
الرمز المميز 3:>
الرمز المميز 4: 0
استنتج: x--> 0
تنطبق نفس القاعدة على هذا التعبير:
أ ----- ب
بعد التحليل:
الرمز المميز 1: أ
الرمز المميز 2: -
الرمز المميز 3: -
الرمز المميز 4: -
الرمز المميز 5: ب
نستنتج: (أ -) - - ب
آمل أن يساعد هذا في فهم التعبير المعقد ^ ^
|
هذا هو بالضبط نفس
بينما (س--)
{
printf ("٪ d" ، x) ؛
}
للأرقام غير السالبة
|
على أي حال ، لدينا عامل "يذهب إلى" الآن. من السهل تذكر "->" كاتجاه ، و "بينما يذهب x إلى الصفر" هو معنى مستقيم.
علاوة على ذلك ، فهي أكثر فاعلية من "(x = 10 ؛ x> 0 ؛ x -)" في بعض الأنظمة الأساسية.
|
يقارن هذا الرمز أولاً x و 0 ثم ينقص x. (قيل أيضًا في الإجابة الأولى: أنت تقوم بعد بتقليل x ثم تقارن x و 0 مع عامل التشغيل>.) انظر إخراج هذا الكود:
9 8 7 6 5 4 3 2 1 0
نحن الآن نقارن أولاً ثم ننقص برؤية 0 في الناتج.
إذا أردنا التناقص أولاً ثم المقارنة ، فاستخدم هذا الكود:
# تضمين 
int main (باطل)
{
كثافة العمليات س = 10 ؛
بينما (--x> 0) // x يذهب إلى 0
{
printf ("٪ d" ، x) ؛
}
العودة 0 ؛
}
هذا الناتج هو:
9 8 7 6 5 4 3 2 1
|
سيقوم المترجم بطباعة 9876543210 عندما أقوم بتشغيل هذا الرمز.
# تضمين 
انت مين()
{
كثافة العمليات س = 10 ؛
بينما (x -> 0) // x يذهب إلى 0
{
الأمراض المنقولة جنسيا :: cout << x ؛
}
}
كما هو متوقع. بينما تعني كلمة while (x--> 0) فعلاً while (x> 0). إنقاص x- بعد x.
بينما (x> 0)
{
س-- ؛
الأمراض المنقولة جنسيا :: cout << x ؛
}
هي طريقة مختلفة لكتابة نفس الشيء.
من الجيد أن تبدو النسخة الأصلية "بينما x يذهب إلى 0".
|
توجد مسافة مفقودة بين - و>. x هو post decremented ، أي تناقص بعد التحقق من الشرط x> 0؟.
|
- هو عامل التشغيل التناقص و> أكبر من عامل التشغيل.
يتم تطبيق عاملي التشغيل على أنهما عامل واحد مثل ->.
|
إنه مزيج من عاملين. الأول - لإنقاص القيمة ، و> للتحقق مما إذا كانت القيمة أكبر من المعامل الأيمن.
# تضمين 
انت مين()
{
كثافة العمليات س = 10 ؛
بينما (x--> 0)
printf ("٪ d" ، x) ؛
العودة 0 ؛
}
سيكون الإخراج:
9 8 7 6 5 4 3 2 1 0
|
في الواقع ، x هو بعد التناقص وبهذا الشرط قيد التحقق. إنه ليس -> ، إنه (x--)> 0
ملاحظة: يتم تغيير قيمة x بعد التحقق من الشرط ، لأنها تتناقص لاحقًا. يمكن أن تحدث بعض الحالات المماثلة أيضًا ، على سبيل المثال:
-> س -> 0
++> x ++> 0
-> = س -> = 0
++> = x ++> = 0
|
تخضع C و C ++ لقاعدة "الحد الأقصى للقضم". بنفس طريقة ترجمة a --- b إلى (a--) - b ، في حالتك تُترجم x -> 0 إلى (x -)> 0.
ما تقوله القاعدة بشكل أساسي هو أنه من اليسار إلى اليمين ، يتم تكوين التعبيرات بأخذ أقصى عدد من الأحرف التي ستشكل تعبيرًا صالحًا.
|
لماذا كل هذا التعقيد؟
الجواب البسيط على السؤال الأصلي هو:
# تضمين 
انت مين()
{
كثافة العمليات س = 10 ؛
بينما (x>0)
{
printf ("٪ d" ، x) ؛
س = س -1 ؛
}
}
وهو يفعل الشيء نفسه. أنا لا أقول أنه يجب عليك القيام بذلك على هذا النحو ، لكنه يفعل نفس الشيء وكان سيجيب على السؤال في منشور واحد.
إن x-- هو مجرد اختصار لما ورد أعلاه ، و> مجرد عامل عادي أكبر من عامل التشغيل. لا لغز كبير!
هناك الكثير من الناس يجعلون الأشياء البسيطة معقدة في الوقت الحاضر ؛)
|
بالطريقة التقليدية ، نحدد شرطًا في قوس حلقة while () وشرط إنهاء داخل الأقواس {} ، ولكن -> يحدد كلاهما مرة واحدة.
فمثلا:
int abc (باطل)
{
الباحث أ = 5
while ((a--)> 0) // التناقص والمقارنة معًا في وقت واحد
{
// الشفرة
}
}
يؤدي هذا إلى تقليل a وتشغيل الحلقة بينما a أكبر من 0.
بشكل تقليدي ، سيكون مثل:
int abc (باطل)
{
الباحث أ = 5 ؛
بينما (أ> 0)
{
أ--؛
// الشفرة
}
أ--؛
}
في كلا الاتجاهين ، نفعل الشيء نفسه ونحقق نفس الأهداف.
|
(x -> 0) تعني (x--> 0).
يمكنك استخدام (x ->) الإخراج: 9 8 7 6 5 4 3 2 1 0
يمكنك استخدام (- x> 0) يعني (--x> 0) الإخراج: 9 8 7 6 5 4 3 2 1
يمكنك استخدام
(- \
\
x> 0)
الخرج: 9 8 7 6 5 4 3 2 1
يمكنك استخدام
(\
\
س -> 0)
الخرج: 9 8 7 6 5 4 3 2 1 0
يمكنك استخدام
(\
\
س -> 0
\
\
)
الخرج: 9 8 7 6 5 4 3 2 1 0
يمكنك أيضا استخدام ملفات
(
x
->
)
الخرج: 9 8 7 6 5 4 3 2 1 0
وبالمثل ، يمكنك تجربة العديد من الطرق لتنفيذ هذا الأمر بنجاح.
|
هنا - هو عامل التناقص اللاحق الأحادي.
بينما (x--> 0) // x يذهب إلى 0
{
printf ("٪ d" ، x) ؛
}
في البداية ، سيتم تقييم الحالة على أنها
(x> 0) // 10> 0
الآن لأن الشرط صحيح ، سوف يدخل الحلقة بقيمة متناقصة
س - // س = 9
هذا هو السبب في أن أول قيمة مطبوعة هي 9
وهلم جرا. في الحلقة الأخيرة x = 1 ، يكون الشرط صحيحًا. وفقًا للعامل الأحادي ، تغيرت القيمة إلى x = 0 في وقت الطباعة.
الآن ، x = 0 ، والتي تقيم الشرط (x> 0) على أنها خطأ وتخرج حلقة while.
|
هذا -> ليس عامل تشغيل على الإطلاق. لدينا عامل مثل -> ، ولكن ليس مثل ->. إنه مجرد تفسير خاطئ لـ while (x--> 0) مما يعني ببساطة أن x لديه عامل التناقص اللاحق وأن هذه الحلقة ستستمر حتى تصبح أكبر من الصفر.
طريقة أخرى بسيطة لكتابة هذا الرمز هي while (x--). ستتوقف حلقة while عندما تحصل على حالة خاطئة وهنا توجد حالة واحدة فقط ، أي 0. لذلك ستتوقف عندما تنخفض قيمة x إلى الصفر.
|
سؤال نشط للغاية. اكسب 10 سمعة للإجابة على هذا السؤال. تساعد متطلبات السمعة في حماية هذا السؤال من البريد العشوائي ونشاط عدم الإجابة.
ليس الجواب الذي تبحث عنه؟ تصفح الأسئلة الأخرى الموسومة بعلامات امتثال معايير تنسيق التعليمات البرمجية لمشغلي c ++ c أو اطرح سؤالك الخاص.